using FSM.IDal; 
using FSM.IBll; 
using FSM.Model; 
using SqlSugar; 
using System; 
using System.Collections.Generic; 
using System.Text;
using System.Linq;
using Util.Extensions;

namespace FSM.Bll 
{ 
    public class RelRoleMenuBll: IRelRoleMenuBll 
    { 
        #region 模块 
        private readonly IRelRoleMenuDal dal;
        private readonly IRelRoleMenuActionDal relRoleMenuActionDal;
        public RelRoleMenuBll(IRelRoleMenuDal dal, IRelRoleMenuActionDal relRoleMenuActionDal) 
        { 
            this.dal = dal;
            this.relRoleMenuActionDal = relRoleMenuActionDal;
        } 
        #endregion 
 
        #region 查询 
 
        /// <summary> 
        /// 根据键值查询单个信息 
        /// </summary> 
        /// <param name="pkid">键值</param> 
        /// <returns></returns> 
        public rel_role_menu Get(string pkid) 
        { 
            return dal.GetById(pkid); 
        } 
 
        /// <summary> 
        /// 查询批量信息 
        /// </summary> 
        /// <param name="role_no">角色编号</param> 
        /// <param name="menu_no">菜单编号</param> 
        /// <param name="page">页码</param> 
        /// <param name="page_size">每页显示的条数</param> 
        /// <returns></returns> 
        public Tuple<List<rel_role_menu>, int> List(string role_no, string menu_no, int page, int page_size) 
        { 
            ISugarQueryable<rel_role_menu> queryable = dal.CreateQueryable(); 
            queryable = queryable.WhereIF(!string.IsNullOrEmpty(role_no),p => p.role_no == role_no); 
            queryable = queryable.WhereIF(!string.IsNullOrEmpty(menu_no),p => p.menu_no == menu_no); 
             
            PageModel pm = new PageModel 
            { 
                PageIndex = page, 
                PageSize = page_size 
            }; 
            Tuple<List<rel_role_menu>, int> result = dal.GetPageListAndTotal(queryable, pm); 
            return result; 
        }

        /// <summary>
        /// 根据角色获得其拥有的菜单及对应的动作编号信息
        /// </summary>
        /// <param name="role_no">角色编号</param>
        /// <returns></returns>
        public List<string> ListMenusAndActionKeysByRoleNo(string role_no)
        {
            List<string> result = new List<string>();
            List<rel_role_menu> rmModels = dal.GetList(p => p.role_no == role_no);
            result.AddRange(rmModels.Select(p => p.menu_no));
            foreach (var rm in rmModels)
            {
                IEnumerable<string> tempKeys = relRoleMenuActionDal.GetList(p => p.role_menu_id == rm.pkid).Select(p => p.act_no);
                if (tempKeys.Count() > 0)
                {
                    foreach (string item in tempKeys)
                    {
                        result.Add($"{rm.menu_no}|{item}");
                    }
                }
            }
            return result;
        }
 
        #endregion 
 
        #region 提交 
 
        /// <summary> 
        /// 添加 
        /// </summary> 
        /// <param name="model">实体</param> 
        /// <returns></returns> 
        public bool Insert(rel_role_menu model) 
        {
            if (model.role_no.ToLower() == "administrators")
            {
                throw new Exception("你没有权限修改此角色");
            }
            model.create_date = DateTime.Now; 
            return dal.Insert(model); 
        }

        /// <summary>
        /// 赋于角色对应的菜单信息
        /// </summary>
        /// <param name="oper">操作人员</param>
        /// <param name="role_no">角色编号</param>
        /// <param name="menu_nos">菜单编号列表</param>
        /// <returns></returns>
        public bool BatchInsert(string oper, string role_no, List<string> menu_nos)
        {
            dal.BeginTran();
            try
            {
                oper.ValidEmptyThrowException("操作人员");
                role_no.ValidEmptyThrowException("要操作的角色");

                if (role_no.ToLower() == "administrators")
                {
                    throw new Exception("你没有权限修改此角色");
                }

                DateTime dtNow = DateTime.Now;
                //查询菜单信息
                IEnumerable<string> menuNos = menu_nos.Where(p => p.IndexOf("|") == -1);
                //查询菜单的动作信息
                IEnumerable<string> actionNos = menu_nos.Where(p => p.IndexOf("|") > -1);

                //先获得原来拥有的菜单信息
                List<rel_role_menu> oldRelRoleMenus = dal.GetList(p => p.role_no == role_no);
                //查询旧的菜单编号信息
                List<string> oldMenuNos = oldRelRoleMenus.Select(p => p.menu_no).ToList();

                bool success = false;
                //删除原来拥有，现在没有的菜单信息
                IEnumerable<string> deletePkids = oldRelRoleMenus.Where(p => menu_nos.Contains(p.menu_no) == false).Select(p => p.pkid);
                if (deletePkids.Count() > 0)
                {
                    success = dal.Delete(deletePkids.ToArray());
                    if (success == false)
                    {
                        throw new Exception("移除原有菜单权限失败");
                    }
                }

                //添加新增的菜单信息
                IEnumerable<string> newMenuNos = menuNos.Where(p => oldMenuNos.Contains(p) == false);
                if (newMenuNos.Count() > 0)
                {
                    List<rel_role_menu> roleMenuModels = new List<rel_role_menu>();
                    foreach (string no in newMenuNos)
                    {
                        rel_role_menu roleMenuModel = new rel_role_menu() { 
                            pkid = Guid.NewGuid().ToString("N"),
                            role_no = role_no,
                            menu_no = no,
                            creater = oper,
                            create_date = dtNow
                        };
                        roleMenuModels.Add(roleMenuModel);
                    }
                    success = dal.Insert(roleMenuModels);
                    if (success == false)
                    {
                        throw new Exception("新增新菜单权限失败");
                    }
                }

                //新增动作信息
                Dictionary<string, List<string>> roleMenuPkidDic = new Dictionary<string, List<string>>();
                foreach (string item in actionNos)
                {
                    string[] temp = item.Split('|');
                    if (roleMenuPkidDic.ContainsKey(temp[0]))
                    {
                        roleMenuPkidDic[temp[0]].Add(temp[1]);
                    }
                    else
                    {
                        roleMenuPkidDic.Add(temp[0], new List<string>() { temp[1] });
                    }
                }
                if (roleMenuPkidDic.Count > 0)
                {
                    foreach (var item in roleMenuPkidDic)
                    {
                        //查询角色菜单对应关系的ID
                        rel_role_menu rmModel = dal.GetSingle(p => p.role_no == role_no && p.menu_no == item.Key);
                        if (rmModel == null)
                        {
                            throw new Exception("角色菜单对应关系不存在，请确认后再试");
                        }
                        //查询角色菜单关系对应的动作信息
                        List<rel_role_menu_action> rmaList = relRoleMenuActionDal.GetList(p => p.role_menu_id == rmModel.pkid);
                        IEnumerable<string> oldActNos = rmaList.Select(p => p.act_no);
                        //删除原来拥有，现在没有的动作信息
                        deletePkids = rmaList.Where(p => item.Value.Contains(p.act_no) == false).Select(p => p.pkid);
                        if (deletePkids.Count() > 0)
                        {
                            success = relRoleMenuActionDal.Delete(deletePkids.ToArray());
                            if (success == false)
                            {
                                throw new Exception("移除动作信息失败");
                            }
                        }

                        //添加新增的动作信息
                        IEnumerable<string> newActNos = item.Value.Where(p => oldActNos.Contains(p) == false);
                        if (newActNos.Count() > 0)
                        {
                            List<rel_role_menu_action> rmaModels = new List<rel_role_menu_action>() {};
                            foreach (var no in newActNos)
                            {
                                rel_role_menu_action rma = new rel_role_menu_action()
                                {
                                    pkid = Guid.NewGuid().ToString("N"),
                                    role_menu_id = rmModel.pkid,
                                    act_no = no,
                                    creater = oper,
                                    create_date = dtNow
                                };
                                rmaModels.Add(rma);
                            }
                            success = relRoleMenuActionDal.Insert(rmaModels);
                            if (success == false)
                            {
                                throw new Exception("新增菜单动作权限失败");
                            }
                        }
                    }                    
                }

                dal.CommitTran();
                return true;
            }
            catch (Exception)
            {
                dal.RollbackTran();
                throw;
            }
        }

        /// <summary> 
        /// 更新 
        /// </summary> 
        /// <param name="model">实体</param> 
        /// <returns></returns> 
        public bool Update(rel_role_menu model) 
        {
            if (model.role_no.ToLower() == "administrators")
            {
                throw new Exception("你没有权限修改此角色");
            }
            model.edit_date = DateTime.Now; 
            return dal.UpdateExcludeColumns(model, "creater", "create_date") == 1; 
        } 
 
        /// <summary> 
        ///  删除 
        /// </summary> 
        /// <param name="pkid">键值</param> 
        /// <returns></returns> 
        public bool Delete(params string[] pkid_arr) 
        {
            return dal.Delete(pkid_arr); 
        } 
        #endregion 
    } 
} 
